﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using AmiEmuLib.AmigaMachine.AmigaMemory;
using AmiEmuLib.AmigaConfiguration.CoreConfig;
using AmiEmuLib.AmigaMachine;
using AmiEmuLib.AmigaConfiguration;
using AmiEmuLib.Configuration;
using AmiEmuLib;
using AmiEmuLib.Configuration.KnownRomConfig;

namespace amiemu_lib_test
{
    public class TestBase
    {
        protected IEnumerable<MemoryBank> CheckBanks(Machine a_machine, uint a_address, uint a_size,
                                                     MemoryBankType a_type)
        {
            for (ulong addr = a_address; addr < a_address + a_size; addr += Consts.BANK_SIZE)
            {
                var bank = a_machine.Memory.GetBank((uint)addr);
                Assert.IsTrue(bank.Type == a_type);
                yield return bank;
            }
        }

        protected void Assert_SameBanks(Machine a_machine1, Machine a_machine2, uint a_address)
        {
            Assert.IsTrue(MemoryHelpers.IsBankAllign(a_address));

            for (uint addr = a_address; addr <= a_address + Consts.BANK_SIZE; addr += 2)
            {
                Assert.IsTrue((a_machine1.Memory.GetWord(addr) == 
                    a_machine2.Memory.GetWord(addr)));
                   
            }
        }

        protected void RomLoadExceptionValid(AmigaConfig a_config)
        {
            Assert.IsTrue(a_config.AmigaModel == AmigaModel.A3000);
            Assert.IsTrue((a_config.Memory.Kickstart.RomType == RomType.A3000_1_4) ||
                (a_config.Memory.Kickstart.RomType == RomType.A3000_3_1));
        }

        protected void CPUIniitalizationExceptionValid(AmigaConfig a_config)
        {
            Assert.IsTrue(
                (a_config.CPU.Model == CPUModel.MC68010) ||
                (a_config.CPU.Model == CPUModel.MC68030) ||
                (a_config.CPU.Model == CPUModel.MC68040) ||
                (a_config.CPU.Model == CPUModel.MC68060) ||
                (a_config.CPU.Model == CPUModel.MC68EC030) ||
                (a_config.CPU.Model == CPUModel.MC68EC040) ||
                (a_config.CPU.Model == CPUModel.MC68EC060) ||
                (a_config.CPU.Model == CPUModel.MC68LC040) ||
                (a_config.CPU.Model == CPUModel.MC68LC060));
        }

        protected MemoryBank GetFirstBank(MemoryBankType a_type, Memory a_memory)
        {
            foreach (var bank in a_memory)
                if (bank.Type == a_type)
                    return bank;
            return null;
        }

        protected void SwapBytes(byte[] a_array)
        {
            for (int i = 0; i < a_array.Length / 2; i++)
            {
                byte t = a_array[i * 2];
                a_array[i * 2] = a_array[i * 2 + 1];
                a_array[i * 2 + 1] = t;
            }
        }

        protected void IsException(Action a_action)
        {
            try
            {
                a_action();
            }
            catch
            {
                return;
            }

            Assert.Fail();
        }
    }
}
